import { Answer, FEEDBACK } from './conversationModels';
import { Doc } from '../preferences/preferenceApi';
import { getToken } from '../login/loginApi';

const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com';

export function fetchAnswerApi(
  question: string,
  signal: AbortSignal,
  selectedDocs: Doc,
  history: Array<any> = [],
  conversationId: string | null,
  promptId: string | null,
  chunks: string,
): Promise<
  | {
      result: any;
      answer: any;
      sources: any;
      conversationId: any;
      query: string;
    }
  | {
      result: any;
      answer: any;
      sources: any;
      query: string;
      conversationId: any;
      title: any;
    }
> {
  let namePath = selectedDocs.name;
  if (selectedDocs.language === namePath) {
    namePath = '.project';
  }

  let docPath = 'default';
  if (selectedDocs.location === 'local') {
    docPath = 'local' + '/' + selectedDocs.name + '/';
  } else if (selectedDocs.location === 'remote') {
    docPath =
      selectedDocs.language +
      '/' +
      namePath +
      '/' +
      selectedDocs.version +
      '/' +
      selectedDocs.model +
      '/';
  }
  //in history array remove all keys except prompt and response
  history = history.map((item) => {
    return { prompt: item.prompt, response: item.response };
  });

  return fetch(apiHost + '/api/answer', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      question: question,
      history: history,
      active_docs: docPath,
      conversation_id: conversationId,
      prompt_id: promptId,
      chunks: chunks,
    }),
    signal,
  })
    .then((response) => {
      if (response.ok) {
        return response.json();
      } else {
        return Promise.reject(new Error(response.statusText));
      }
    })
    .then((data) => {
      const result = data.answer;
      return {
        answer: result,
        query: question,
        result,
        sources: data.sources,
        conversationId: data.conversation_id,
      };
    });
}

export function fetchAnswerSteaming(
  question: string,
  signal: AbortSignal,
  selectedDocs: Doc,
  history: Array<any> = [],
  conversationId: string | null,
  promptId: string | null,
  chunks: string,
  onEvent: (event: MessageEvent) => void,
): Promise<Answer> {
  let namePath = selectedDocs.name;
  if (selectedDocs.language === namePath) {
    namePath = '.project';
  }

  // 从ssionStorage里取,如果是空那就是空字符串
  let docPath = sessionStorage.getItem('selectedFiles') || '';

  history = history.map((item) => {
    return { question: item.prompt, answer: item.response };
  });

  const prompt_storage =  sessionStorage.getItem('prompt')

  return new Promise<Answer>((resolve, reject) => {
   
    let historyToUse = history.slice(-3); // 上下文的只取前三轮
    const body = {
      question: question,
      active_docs: docPath,
      history: historyToUse,
      conversation_id: conversationId,
      conversion_name:'',
      prompt_id: prompt_storage,
      chunks: chunks,
      stream: true,
    };
    // 如果conversationId不为空，则添加conversion_name字段到body中
    if (!conversationId) {
      body.conversion_name = question;
    }
    const apiHost = import.meta.env.VITE_API_HOST || '';
    fetch(apiHost+'/conversion/stream', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${getToken()}`,
      },
      body: JSON.stringify(body),
      signal,
    })
    .then((response) => {
      if (!response.body) throw Error('No response body');

      const reader = response.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let counterrr = 0;
      const processStream = ({
        done,
        value,
      }: ReadableStreamReadResult<Uint8Array>) => {
        if (done) {
          console.log(counterrr,"end",conversationId);
          const jsonDataId = JSON.stringify({"type": "id", "id": conversationId});
          const messageEvent: MessageEvent = new MessageEvent('message', {
            data: jsonDataId,
          });
          const jsonDataEnd = JSON.stringify({"type": "end"});
          const messageEventEnd: MessageEvent = new MessageEvent('message', {
            data: jsonDataEnd,
          });
          onEvent(messageEvent); // handle each message
          onEvent(messageEventEnd); 
          return;
        }

        counterrr += 1;

        const chunk = decoder.decode(value);

  

          const jsonData = JSON.stringify({ "answer": chunk });
          const messageEvent: MessageEvent = new MessageEvent('message', {
            data: jsonData,
          });

          onEvent(messageEvent); // handle each message
  

        reader.read().then(processStream).catch((err)=>{
          console.log("errir1" , err)
        }),reject;
      };
      reader.read().then(processStream).catch((err)=>{
        console.log("errir2" , err)
      }),reject;
    })
    .catch((error) => {
      console.error('Connection failed:', error);
      reject(error);
    });
  });
}
export function searchEndpoint(
  question: string,
  selectedDocs: Doc,
  conversation_id: string | null,
  history: Array<any> = [],
  chunks: string,
) {
  /*
  "active_docs": "default",
  "question": "Summarise",
  "conversation_id": null,
  "history": "[]" */
  let namePath = selectedDocs.name;
  if (selectedDocs.language === namePath) {
    namePath = '.project';
  }

  let docPath = 'default';
  if (selectedDocs.location === 'local') {
    docPath = 'local' + '/' + selectedDocs.name + '/';
  } else if (selectedDocs.location === 'remote') {
    docPath =
      selectedDocs.language +
      '/' +
      namePath +
      '/' +
      selectedDocs.version +
      '/' +
      selectedDocs.model +
      '/';
  }

  const body = {
    question: question,
    active_docs: docPath,
    conversation_id,
    history,
    chunks: chunks,
  };

  const apiHost = import.meta.env.VITE_API_HOST || '';
  return fetch(apiHost+`/conversion/search_docs`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${getToken()}`,
    },
    body: JSON.stringify(body),
  })
    .then((response) => response.json())
    .then((data) => {
      return data;
    })
    .catch((err) => console.log(err));
}
export function sendFeedback(
  prompt: string,
  response: string,
  feedback: FEEDBACK,
) {
  return fetch(`${apiHost}/api/feedback`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      question: prompt,
      answer: response,
      feedback: feedback,
    }),
  }).then((response) => {
    if (response.ok) {
      return Promise.resolve();
    } else {
      return Promise.reject();
    }
  });
}
